package com.mkl.ttxt.pd.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.mkl.ttxt.common.constant.BaseConstant;
import com.mkl.ttxt.common.exception.BusinessException;
import com.mkl.ttxt.pd.bo.*;
import com.mkl.ttxt.pd.dao.IBoxDao;
import com.mkl.ttxt.pd.dao.IPdDao;
import com.mkl.ttxt.pd.service.IBoxService;
import com.mkl.ttxt.pd.service.IPdService;
import com.mkl.ttxt.pd.util.PlanUtil;
import com.mkl.ttxt.remote.util.ExcelUtil;
import io.netty.util.internal.StringUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

import static java.util.stream.Collectors.toList;

@Service
@Transactional
public class BoxImpl implements IBoxService {

    @Autowired
    IBoxDao iBoxDao;
    @Autowired
    IPdDao iPdDao;

    @Override
    public void excelImportBox(MultipartFile file, Integer userId, int type) {
        //清空原有box、组合、成员、成员可用阵容(保留阵容)
        iPdDao.cleanBox(userId);
        iPdDao.cleanMemberLineup(userId);
        iPdDao.cleanPossibleCompose(userId);
        iBoxDao.cleanMember(userId);

        List<MemberOrCard> memberList;
        try{
            memberList = parseMemberExcel(file, type);
        }catch (Exception e){
            throw new BusinessException("解析excel异常，请检查表格格式，表头不动，没有的填0");
        }

        for(MemberOrCard member : memberList){
            iBoxDao.addMember(member, userId);
            for(Box box: member.getBox()){
                iBoxDao.addBox(box, member.getId(), userId);
            }
        }

    }

    @Override
    public void excelImportLineup(MultipartFile file, Integer userId, int type) throws IOException {
        //清除阵容，成员可用阵容、组合
        iPdDao.cleanPossibleCompose(userId);
        iPdDao.cleanMemberLineup(userId);
        iPdDao.cleanLineup(userId);

        List<Lineup> lineupList = parseLineupExcel(file, type);
        for(Lineup lineup: lineupList){
            iPdDao.addLineup(lineup, userId);
        }
    }

    @Override
    public Object getAllParam(Integer userId) {
        List<Param> paramList = iBoxDao.getAllParam(userId);
        return paramList;
    }

    @Override
    public void initParam(Integer userId) {
        iBoxDao.cleanParam(userId);
        List<Param> paramList = new ArrayList<>();
        Param param = new Param();
        param.setParamKey("尾刀血线");
        param.setParamValue("20");
        paramList.add(param);
        param = new Param();
        param.setParamKey("一阶段1王分数倍率");
        param.setParamValue("10");
        paramList.add(param);
        param = new Param();
        param.setParamKey("一阶段2王分数倍率");
        param.setParamValue("10");
        paramList.add(param);
        param = new Param();
        param.setParamKey("一阶段3王分数倍率");
        param.setParamValue("10");
        paramList.add(param);
        param = new Param();
        param.setParamKey("一阶段4王分数倍率");
        param.setParamValue("10");
        paramList.add(param);
        param = new Param();
        param.setParamKey("一阶段5王分数倍率");
        param.setParamValue("10");
        paramList.add(param);
        param = new Param();
        param.setParamKey("一阶段6王分数倍率");
        param.setParamValue("10");
        paramList.add(param);

        param = new Param();
        param.setParamKey("二阶段1王分数倍率");
        param.setParamValue("10");
        paramList.add(param);
        param = new Param();
        param.setParamKey("二阶段2王分数倍率");
        param.setParamValue("11");
        paramList.add(param);
        param = new Param();
        param.setParamKey("二阶段3王分数倍率");
        param.setParamValue("15");
        paramList.add(param);
        param = new Param();
        param.setParamKey("二阶段4王分数倍率");
        param.setParamValue("12");
        paramList.add(param);
        param = new Param();
        param.setParamKey("二阶段5王分数倍率");
        param.setParamValue("20");
        paramList.add(param);
        param = new Param();
        param.setParamKey("二阶段6王分数倍率");
        param.setParamValue("18");
        paramList.add(param);

        param = new Param();
        param.setParamKey("三阶段1王分数倍率");
        param.setParamValue("0");
        paramList.add(param);
        param = new Param();
        param.setParamKey("三阶段2王分数倍率");
        param.setParamValue("0");
        paramList.add(param);
        param = new Param();
        param.setParamKey("三阶段3王分数倍率");
        param.setParamValue("0");
        paramList.add(param);
        param = new Param();
        param.setParamKey("三阶段4王分数倍率");
        param.setParamValue("0");
        paramList.add(param);
        param = new Param();
        param.setParamKey("三阶段5王分数倍率");
        param.setParamValue("0");
        paramList.add(param);
        param = new Param();
        param.setParamKey("三阶段6王分数倍率");
        param.setParamValue("0");
        paramList.add(param);

        iBoxDao.batchInsert(paramList, userId);
    }

    @Override
    public void updateParam(Param param, Integer userId) {
        try{
            Integer value = Integer.valueOf(param.getParamValue());
            if(value < 0 || value > 1000){
                throw new BusinessException("参数为0-1000的整数");
            }
        }catch (Exception e){
            throw e;
        }
        iBoxDao.updateParam(param.getId(), param.getParamValue(), userId);
    }

    @Override
    public void calParam(Integer userId) {
        iBoxDao.setWeightZero(userId);
        //找各王最高伤阵容
        List<Lineup> maxLineUpList = iBoxDao.getMaxLineUpDamageList(userId);
        //最高伤反比为权重，定义第一个boss为100，做基准
        Integer firstDamage = null;
        Integer firstWeight = 100;
        for(Lineup maxLineup: maxLineUpList){
            if(firstDamage == null){
                firstDamage = maxLineup.getDamage();
                String paramKey = getKeyByBossNo(maxLineup.getBossNo());
                iBoxDao.updateParamByKey(userId, paramKey, String.valueOf(firstWeight));
            }else{
                Integer damage = maxLineup.getDamage();
                Integer weight = firstDamage * firstWeight / damage;
                String paramKey = getKeyByBossNo(maxLineup.getBossNo());
                iBoxDao.updateParamByKey(userId, paramKey, String.valueOf(weight));
            }
        }
    }

    @Override
    public void recordDamage(Record record, Integer userId) {
        iBoxDao.recordDamage(record, userId);
    }

    private String getKeyByBossNo(Integer bossNo) {
        switch(bossNo){
            case 11:
                return "一阶段1王分数倍率";
            case 12:
                return "一阶段2王分数倍率";
            case 13:
                return "一阶段3王分数倍率";
            case 14:
                return "一阶段4王分数倍率";
            case 15:
                return "一阶段5王分数倍率";
            case 16:
                return "一阶段6王分数倍率";
            case 21:
                return "二阶段1王分数倍率";
            case 22:
                return "二阶段2王分数倍率";
            case 23:
                return "二阶段3王分数倍率";
            case 24:
                return "二阶段4王分数倍率";
            case 25:
                return "二阶段5王分数倍率";
            case 26:
                return "二阶段6王分数倍率";
            case 31:
                return "三阶段1王分数倍率";
            case 32:
                return "三阶段2王分数倍率";
            case 33:
                return "三阶段3王分数倍率";
            case 34:
                return "三阶段4王分数倍率";
            case 35:
                return "三阶段5王分数倍率";
            case 36:
                return "三阶段6王分数倍率";
            default:
                throw new BusinessException("Boss编号异常");
        }
    }

    private List<Lineup> parseLineupExcel(MultipartFile file, int type) {
        try {
            List<Lineup> lineupList = new ArrayList<>();
            Workbook workbook = null;
            if(type == 0){
                workbook = new XSSFWorkbook(file.getInputStream());
            }else{
                workbook = new HSSFWorkbook(file.getInputStream());
            }
            Sheet sheet = workbook.getSheetAt(0);
            Iterator<Row> rows = sheet.iterator();
            int rowNumber = 1;
            while (rows.hasNext()) {
                Row currentRow = rows.next();
                if (rowNumber < 2) {
                    //跳过头
                    rowNumber++;
                    continue;
                }
                if(StringUtil.isNullOrEmpty(ExcelUtil.convertCellValueToString(currentRow.getCell(0)))){
                    break;
                }
                Lineup lineup = new Lineup();
                //解析阵容
                lineup.setBossNo(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(0))));
                lineup.setRemark(ExcelUtil.convertCellValueToString(currentRow.getCell(1)));
                lineup.setDamage(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(2))));
                List<LineupCard> lineupCardList = new ArrayList<>();
                //遍历列，找卡的星级
                Iterator<Cell> cells = currentRow.cellIterator();
                int cellNumber = 1;
                while (cells.hasNext()) {
                    Cell currentCell = cells.next();
                    if (cellNumber < 4) {
                        cellNumber++;
                        continue;
                    }
                    if(!StringUtil.isNullOrEmpty(ExcelUtil.convertCellValueToString(currentCell))){
                        LineupCard lineupCard = new LineupCard();
                        lineupCard.setStar(ExcelUtil.convertCellValueToString(currentCell));
                        lineupCard.setCardId(getCardId(currentCell.getColumnIndex() + 1));
                        lineupCardList.add(lineupCard);
                    }
                    if(lineupCardList.size() >= 5){
                        break;
                    }
                    cellNumber++;
                }

                if(lineupCardList.size() != 5){
                    throw new BusinessException(lineup.getRemark() + "未满五人");
                }
                lineup.setLineup(JSON.toJSONString(lineupCardList));
                lineupList.add(lineup);
                rowNumber++;
            }
            return lineupList;
        } catch (IOException e) {
            e.printStackTrace();
            throw new BusinessException(e.getMessage());
        }
    }

    private Integer getCardId(int cellNumber) {
        //根据列号转cardId
        Integer result = null;
        switch(cellNumber){
            case 4:
                result = 1;
                break;
            case 5:
                result = 2;
                break;
            case 6:
                result = 3;
                break;
            case 7:
                result = 4;
                break;
            case 8:
                result = 5;
                break;
            case 9:
                result = 6;
                break;
            case 10:
                result = 7;
                break;
            case 11:
                result = 8;
                break;
            case 12:
                result = 9;
                break;
            case 13:
                result = 10;
                break;
            case 14:
                result = 11;
                break;
            case 15:
                result = 12;
                break;
            case 16:
                result = 13;
                break;
            case 17:
                result = 14;
                break;
            case 18:
                result = 15;
                break;
            case 19:
                result = 16;
                break;
            case 20:
                result = 17;
                break;
            case 21:
                result = 18;
                break;
            case 22:
                result = 19;
                break;
            case 23:
                result = 20;
                break;
            case 24:
                result = 21;
                break;
            case 25:
                result = 22;
                break;
            case 26:
                result = 25;
                break;
            case 27:
                result = 26;
                break;
            case 28:
                result = 27;
                break;
            case 29:
                result = 28;
                break;
            case 30:
                result = 29;
                break;
            case 31:
                result = 30;
                break;
            case 32:
                result = 31;
                break;
            case 33:
                result = 32;
                break;
            case 34:
                result = 101;
                break;
            case 35:
                result = 102;
                break;
            case 36:
                result = 103;
                break;
            case 37:
                result = 104;
                break;
            case 38:
                result = 105;
                break;
            case 39:
                result = 106;
                break;
            case 40:
                result = 107;
                break;
            case 41:
                result = 108;
                break;
            case 42:
                result = 109;
                break;
            case 43:
                result = 110;
                break;
            default:
                throw new BusinessException("模板异常");
        }
        return result;
    }

    private List<MemberOrCard> parseMemberExcel(MultipartFile file, int type){
        try {
            List<MemberOrCard> memberList = new ArrayList<>();
            Workbook workbook = null;
            if(type == 0){
                workbook = new XSSFWorkbook(file.getInputStream());
            }else{
                workbook = new HSSFWorkbook(file.getInputStream());
            }
            Sheet sheet = workbook.getSheetAt(0);
            Iterator<Row> rows = sheet.iterator();
            int rowNumber = 1;
            while (rows.hasNext()) {
                Row currentRow = rows.next();
                if (rowNumber < 2) {
                    rowNumber++;
                    continue;
                }
                if(rowNumber > 31){
                    break;
                }
                MemberOrCard member = new MemberOrCard();
                member.setName(ExcelUtil.convertCellValueToString(currentRow.getCell(0)));
                List<Box> boxList = new ArrayList<>();
                Box box = new Box();
                box.setCardId(1);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(1))));
                boxList.add(box);
                box = new Box();
                box.setCardId(2);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(2))));
                boxList.add(box);
                box = new Box();
                box.setCardId(3);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(3))));
                boxList.add(box);
                box = new Box();
                box.setCardId(4);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(4))));
                boxList.add(box);
                box = new Box();
                box.setCardId(5);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(5))));
                boxList.add(box);
                box = new Box();
                box.setCardId(6);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(6))));
                boxList.add(box);
                box = new Box();
                box.setCardId(7);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(7))));
                boxList.add(box);
                box = new Box();
                box.setCardId(8);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(8))));
                boxList.add(box);
                box = new Box();
                box.setCardId(9);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(9))));
                boxList.add(box);
                box = new Box();
                box.setCardId(10);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(10))));
                boxList.add(box);
                box = new Box();
                box.setCardId(11);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(11))));
                boxList.add(box);
                box = new Box();
                box.setCardId(12);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(12))));
                boxList.add(box);
                box = new Box();
                box.setCardId(13);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(13))));
                boxList.add(box);
                box = new Box();
                box.setCardId(14);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(14))));
                boxList.add(box);
                box = new Box();
                box.setCardId(15);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(15))));
                boxList.add(box);
                box = new Box();
                box.setCardId(16);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(16))));
                boxList.add(box);
                box = new Box();
                box.setCardId(17);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(17))));
                boxList.add(box);
                box = new Box();
                box.setCardId(18);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(18))));
                boxList.add(box);
                box = new Box();
                box.setCardId(19);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(19))));
                boxList.add(box);
                box = new Box();
                box.setCardId(20);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(20))));
                boxList.add(box);
                box = new Box();
                box.setCardId(21);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(21))));
                boxList.add(box);
                box = new Box();
                box.setCardId(22);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(22))));
                boxList.add(box);
                box = new Box();
                box.setCardId(25);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(23))));
                boxList.add(box);
                box = new Box();
                box.setCardId(26);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(24))));
                boxList.add(box);
                box = new Box();
                box.setCardId(27);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(25))));
                boxList.add(box);
                box = new Box();
                box.setCardId(28);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(26))));
                boxList.add(box);
                box = new Box();
                box.setCardId(29);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(27))));
                boxList.add(box);
                box = new Box();
                box.setCardId(30);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(28))));
                boxList.add(box);
                box = new Box();
                box.setCardId(31);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(29))));
                boxList.add(box);
                box = new Box();
                box.setCardId(32);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(30))));
                boxList.add(box);
                box = new Box();
                box.setCardId(101);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(31))));
                boxList.add(box);
                box = new Box();
                box.setCardId(102);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(32))));
                boxList.add(box);
                box = new Box();
                box.setCardId(103);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(33))));
                boxList.add(box);
                box = new Box();
                box.setCardId(104);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(34))));
                boxList.add(box);
                box = new Box();
                box.setCardId(105);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(35))));
                boxList.add(box);
                box = new Box();
                box.setCardId(106);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(36))));
                boxList.add(box);
                box = new Box();
                box.setCardId(107);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(37))));
                boxList.add(box);
                box = new Box();
                box.setCardId(108);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(38))));
                boxList.add(box);
                box = new Box();
                box.setCardId(109);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(39))));
                boxList.add(box);
                box = new Box();
                box.setCardId(110);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(40))));
                boxList.add(box);
                box = new Box();
                box.setCardId(111);
                box.setStar(Integer.valueOf(ExcelUtil.convertCellValueToString(currentRow.getCell(41))));
                boxList.add(box);
                member.setBox(boxList);
                memberList.add(member);
                rowNumber++;
            }
            return memberList;
        } catch (IOException e) {
            e.printStackTrace();
            throw new BusinessException(e.getMessage());
        }
    }

}
